from django.utils.translation import ugettext_lazy as _
try:
    from django.contrib.gis.db import models
except ImportError:
    from django.db import models

import libxml2

__all__ = ["OpenSearch"]

class OpenSearch(object):
    ShortName = None
    Description = None
    Url = [{ "type" : "application/xhtml+xml",
         "description" : _("HTML"),
         "template" : "/duetopia/%(app)s/%(model)s/?%(spec)s" },
           { "type" : "application/json",
         "description" : _("JSON"),
         "template" : "/duetopia/%(app)s/%(model)s/json/?%(spec)s" },
           { "type" : "application/vnd.google-earth.kml+xml",
         "description" : _("KML"),
         "template" : "/duetopia/%(app)s/%(model)s/kml/?%(spec)s" }]
    namespaces = {}
    search_terms = []
    display_fields = []
    
    def __init__(self, model):
        self.model = model

    @classmethod
    def contribute_to_class(cls, model, name):
        search = cls(model)
        setattr(model._meta, "search", search)
        
    #@property
    def description(self,host=None):
        doc = libxml2.newDoc("1.0")
        
        osd = libxml2.newNode("OpenSearchDescription")
        osns = osd.newNs("http://a9.com/-/spec/opensearch/1.1/", None)
        osd.setNs(osns)
        for ns in self.namespaces:
            osd.newNs(self.namespaces[ns], ns)
        doc.addChild(osd)

        shortName = self.ShortName or _("Duetopia %(name)s Search") % \
                        {"name" : unicode(self.model._meta.verbose_name)}
        osd.newChild(None, "ShortName", unicode(shortName))

        description = self.Description or _("Search Duetopia for geospatial data")
        osd.newChild(None, "Description", unicode(description))

        ### optional tags that can appear zero or one time and cannot be
        ### determined automatically
        for optional_tag in ["Contact", "LongName", "Developer", "Attribution",
                     "SyndicationRight", "AdultContent"]:
            if hasattr(self, optional_tag):
                tag = getattr(self, optional_tag)
                osd.newChild(None, optional_tag, unicode(tag))
                
        ### optional tags that can appear zero or more times and cannot be
        ### determined automatically
        for optional_tag in ["Language", "InputEncoding", "OutputEncoding"]:
            if not hasattr(self, optional_tag):
                continue
            tags = getattr(self, optional_tag)
            if tags and not isinstance(tags, list) and not isinstance(tags, tuple):
                tags = [tags]
            if tags:
                for tag in tags:
                    osd.newChild(None, optional_tag, unicode(tag))

        for u in self.templates:
            url = osd.newChild(None, "Url", None)
            url.setProp("type", u["type"])
            url.setProp("template", host+u["template"])
        data = doc.serialize("utf-8", True)
        doc.freeDoc()
        return data

    @property
    def templates(self):
        urls = self.Url
        if not isinstance(urls, list) and not isinstance(urls, tuple):
            urls = [urls]
        search_spec = []
        for term in self.search_terms:
            search_spec.append("%(name)s={%(query)s}" % term)
        search_spec = "&".join(search_spec)
        def _get_templates():
            for u in urls:
                v = u.copy()
                v["template"] = u["template"] % {
                    "app" : self.model._meta.app_label,
                    "model" : self.model._meta.module_name,
                    "spec" : search_spec,
                }
                yield v
        return list(_get_templates())

